Tags: depth first search, trees
What is the time complexity of depth first search (DFS) when run on a tree with \(n\) nodes?
\(\Theta(n)\)
Tags: depth first search, aggregate analysis
Suppose an undirected graph \(G = (V, E)\) is a tree with 33 edges. Suppose a node \(s\) is used as the source of a depth-first search.
Including the root call of dfs on node \(s\), how many calls to dfs will be made?
34
Tags: depth first search, breadth first search
Let \(G = (V, E)\) be an undirected tree.
Suppose breadth-first search (BFS) and depth-first search (DFS) are each run on the graph using the same source node. True or False: for any node \(u\) in the graph, the BFS predecessor of \(u\) and the DFS predecessor of \(u\) must be the same.
True.
In a tree there is exactly one simple path from the source to \(u\). BFS and DFS both find a path from the source to \(u\), and it has to be this one, so both predecessors are the node right before \(u\) on it.
Tags: depth first search, breadth first search
Suppose both BFS and DFS are run on the same graph \(G = (V, E)\) using the same source node. Assume that \(G\) is a tree. Consider a particular node \(u\) in the graph. True or False: the BFS predecessor found for \(u\) and the DFS predecessor found for \(u\) must be the same.
True.
In a tree there is exactly one simple path from the source to \(u\). BFS and DFS both find a path from the source to \(u\), and it has to be this one, so both predecessors are the node right before \(u\) on it.
Tags: depth first search, connected components, breadth first search
We saw in lecture that both full BFS and DFS produce trees when run on connected graphs, and forests when run on disconnected graphs. Suppose a full BFS and a full DFS are run on an undirected graph with three connected components. True or False: the number of trees in the BFS forest will equal to number of trees in the DFS forest.
True. Both full BFS and full DFS start a new search once for each connected component (each search discovers exactly the nodes in the source's component), so each produces one tree per connected component: three trees in both forests.
Tags: depth first search
Suppose a depth first search (DFS) is run on the graph shown below using node \(u_4\) as the source and the convention that graph.neighbors produces nodes in ascending order by label. What will be the predecessor of \(u_6\) in the DFS?

\(u_5\). DFS starts at \(u_4\), looks at the neighbors, and sees \(u_2\) is undiscovered, so it makes a recursive call dfs(u_2). At \(u_2\), it sees that \(u_1\) is undiscovered, and calls dfs(u_1). At \(u_1\), there's nothing to do, so it's marked as visited and the recursion unrolls back to the call on dfs(u_2). We then look at the next neighbor of \(u_2\), which is \(u_3\). We make a call to dfs(u_3), which looks at its neighbors and sees \(u_5\). We make a call to dfs(u_5), and during this call we discover \(u_6\), meaning that \(u_5\) is the DFS predecessor of \(u_6\).
Tags: depth first search, start and finish times
Suppose a depth first search is run on the graph shown below using node \(u_4\) as the source, and adopt the convention that graph.neighbors produces nodes in ascending order of label. Which node will have the smallest finish time?

\(u_1\)
Tags: depth first search, start and finish times
Suppose a depth first search is run on the graph shown below using node \(u_4\) as the source, and adopt the convention that graph.neighbors produces nodes in ascending order of label. What will be the start time of node \(u_7\)?

12
Tags: depth first search
Suppose a depth first search is run on the graph below using node \(d\) as the source, and using the convention that a node's neighbors are produced in alphabetical order.

What is the predecessor of node \(v\) in the DFS search tree?
\(r\). From \(d\), DFS first visits \(f\), then (from \(f\)) \(g\), then (from \(g\)) \(r\), and then (from \(r\)) \(v\). So \(v\) is discovered from \(r\).
Tags: depth first search, start and finish times
Suppose a depth first search is run on the graph below in order to find start and finish times using node \(d\) as the source.

Adopt the convention that the first start time is 1, and, as always, that neighbors are produced in ascending order by label. What will be the start and finish times of node \(r\)?
Start time 4, finish time 7. DFS starts \(d\) at 1, \(f\) at 2, \(g\) at 3, and \(r\) at 4. From \(r\) it starts \(v\) at 5, which finishes at 6, and then \(r\) finishes at 7.
Tags: depth first search
Suppose a DFS is run on the graph shown below using node 11 as the source.

What will be the DFS predecessor of node 3 in the search? Use the convention that a node's neighbors are produced in ascending order by label.
1
Tags: depth first search, start and finish times
Suppose a DFS is run on the graph shown below using node 11 as the source. Use the convention that a node's neighbors are produced in ascending order by label.

What will be the start time of node 2? Use the convention that the start time of the source is 1.
4
What will be the finish time of node 10?
11
Tags: depth first search
Suppose a depth first search (DFS) is run on the graph below, starting at node \(a\). Start and finish times are calculated using the convention that the start time of node \(a\) is 1.

What will be the finish time of node \(c\)? Assume the convention that a node's neighbors are produced in alphabetical order.
11
Tags: depth first search
Suppose a depth first search (DFS) is run on the graph below, starting at node \(a\). Start and finish times are calculated using the convention that the start time of node \(a\) is 1.

What will be the finish time of node \(e\)? Assume the convention that a node's neighbors are produced in alphabetical order.
13
Tags: depth first search, start and finish times
Suppose a depth-first search (DFS) is run on the graph shown below using node \(s\) as the source and adopting the convention that a node's neighbors are produced in ascending order of their label.

What will be the start time of node \(u_7\)?
8
What will be the finish time of node \(u_7\)?
9
Which node will be the DFS predecessor of node \(u_7\)?
\(u_6\)
Tags: depth first search
A modification of the dfs function from lecture is shown below. It is the same as the original dfs function, except that it has an added print statement.
def dfs(graph, u, status=None):
"""Start a DFS at `u`."""
# initialize status if it was not passed
if status is None:
status = {node: 'undiscovered' for node in graph.nodes}
status[u] = 'pending'
for v in graph.neighbors(u):
if status[v] == 'undiscovered':
print("Hello!")
dfs(graph, v, status)
status[u] = 'visited'
Consider running this algorithm on the following graph, starting at node \(a\):

How many times will "Hello!" be printed? Note that this is not a full DFS, and that not all nodes are reachable from \(a\).
6
Tags: depth first search
A modification of the dfs function from lecture is shown below. It is the same as the original dfs function, except that it has an added print statement.
def dfs(graph, u, status=None):
"""Start a DFS at `u`."""
# initialize status if it was not passed
if status is None:
status = {node: 'undiscovered' for node in graph.nodes}
status[u] = 'pending'
for v in graph.neighbors(u):
print("Hello!")
if status[v] == 'undiscovered':
dfs(graph, v, status)
status[u] = 'visited'
Consider running this algorithm on the following graph, starting at node \(a\):

How many times will "Hello!" be printed? Note that this is not a full DFS, and that not all nodes are reachable from \(a\).
10
Tags: depth first search, aggregate analysis
Consider the code shown below. It shows DFS as seen in lecture, with one modification: a print statement in the for-loop.
def dfs(graph, u, status=None):
"""Start a DFS at `u`."""
# initialize status if it was not passed
if status is None:
status = {node: 'undiscovered' for node in graph.nodes}
status[u] = 'pending'
for v in graph.neighbors(u):
print("Hello!")
if status[v] == 'undiscovered':
dfs(graph, v, status)
status[u] = 'visited'
How many times will "Hello!" be printed if dfs is run on the graph below using node \(u\) as the source? Note that dfs will not be restarted if the first call does not explore the whole graph.

12
Tags: depth first search
Suppose we define a forward-looking graph with \(n\) nodes to be the directed graph \(G = (V, E)\) with nodes \(u_1, \ldots, u_n\) and the edge \((u_i, u_j)\) if and only if \(i < j\). An example of such a graph with 4 nodes is shown below.

What is the time complexity of depth-first search when run on a forward-looking graph with \(n\) nodes, using node \(u_1\) as the source? State your answer as a function of \(n\) using asymptotic notation.
\(\Theta(n^2)\)
Tags: depth first search, start and finish times
Suppose you run DFS on a graph in which all nodes are reachable from the source node. True or false: the source node will be marked as visited last, only if the graph is undirected.
False. The source is marked as visited last in both directed and undirected graphs. Every other node is reachable from the source, so each is discovered and finished during the recursive calls made by the call on the source, which finishes only after all of them have.
Tags: depth first search
Suppose a DFS is run on a directed graph. Let \(u\) and \(v\) be two nodes in the graph, and assume that the edge \((u, v)\) exists. True or False: it is possible that, at some moment in time, \(u\) is marked as ``visited'' while \(v\) is marked as ``undiscovered''.
False.
Before dfs(u) marks \(u\) as visited, it loops over all of \(u\)'s successors and calls dfs on any that are undiscovered. So by the time \(u\) is visited, \(v\) has been discovered (it is pending or visited).
Tags: depth first search
Suppose a depth first search is run on a directed graph. True or False: it is possible that, at any moment in time, there is a node marked as visited which has a neighbor (successor) that is marked as pending.
True.
Take the graph with edges \((a, b)\) and \((b, a)\) and start the DFS at \(a\). While \(a\) is pending, dfs(b) is called. It sees that \(a\) is already pending and then finishes, so \(b\) is visited while its successor \(a\) is still pending.
Tags: depth first search
Suppose that a depth first search is being performed on an undirected graph, and when dfs is called on a node \(u\), the statuses of all of its neighbors are printed. True or False: it is possible that one of the neighbors is marked as ``visited''.
False.
dfs(u) is only called when \(u\) is undiscovered. If a neighbor \(w\) were already visited, then dfs(w) would have looped over its neighbors, including \(u\), before finishing, so \(u\) would already have been discovered.
Tags: depth first search, start and finish times
Suppose a depth first search (DFS) is run on a connected undirected graph, and there is a node \(u\) which has only one neighbor. True or False: the finish time of node \(u\) will be equal to its start time plus 3.
False. If \(u\) is not the source, its only neighbor is the node it was discovered from, which is already pending. So DFS finds nothing new to visit from \(u\), and \(u\)'s finish time is its start time plus 1. (If \(u\) is the source, its finish time is its start time plus \(2(|V| - 1) + 1\), which equals its start time plus 3 only when the graph has exactly two nodes.)
Tags: depth first search, start and finish times
In a DFS on an undirected graph \(G\), the start time of node \(u\) is 12, while the finish time of node \(u\) is 37. How many nodes were marked pending between the moment that node \(u\) was marked pending and the moment that it was marked visited? Node \(u\) itself should be excluded from your count.
12
Tags: depth first search, start and finish times
Suppose \(T = (V, E)\) is a connected, undirected graph with no cycles (that is, \(T\) is a tree). Suppose a depth first search is run on \(T\) using node s as the source. Assume that node s has two neighbors: \(u\) and \(v\). If \(|V| = 15\), which one of the below represents possible start and finish times of \(u\) and \(v\)? You may assume that graph.neighbors produces neighbors in ascending order of label.
start[u] = 2, finish[u] = 21, start[v] = 22, finish[v] = 29
Tags: depth first search, start and finish times
Let \(G\) be a graph, and suppose \(s\), \(u\), and \(v\) are three nodes in the graph.
Suppose a depth-first search (DFS) is run on \(G\) using node \(s\) as the source and adopting the convention that a node's neighbors are produced in ascending order by label. During this DFS, start and finish times are computed. Suppose it is found that:
Now suppose another DFS is run using node \(s\) as the source, but adopting a different convention about the order in which neighbors are produced. Suppose new_start and new_finish are the start and finish times found by this second DFS. True or False: it must be that
False.
Take the triangle with edges \((s, u)\), \((s, v)\), \((u, v)\). If \(s\)'s neighbors are produced with \(u\) first, then \(v\) is discovered from \(u\) and its interval is nested inside \(u\)'s. If \(v\) comes first, \(u\) is discovered from \(v\) and the nesting is reversed.
Tags: depth first search, start and finish times
Suppose \(v\) is reachable from node \(u\) in a directed graph. A DFS is run on the graph, and node \(u\) is discovered before node \(v\) (its start time is less than \(v\)'s start time). True or false: the finish time of node \(v\) must be less than the finish time of node \(u\).
False. Consider the graph with nodes s, u, and v, and edges (s,u), (u,s), and (s,v), where a DFS is run with node \(s\) as source, going to node u first. u will be finished before v is started (and thus before it is finished, too).
Tags: depth first search
True or False: a depth first search with source node \(s\) is guaranteed to find the longest simple path starting from \(s\) in a connected, undirected graph \(G\) That is, suppose that there is a unique longest simple path in \(G\), and call this path \(p\). True or False: the longest simple path in the DFS forest must be also be \(p\).
False.
Take edges \((s, a)\), \((s, b)\), \((s, c)\), \((a, b)\), \((a, d)\). The unique longest simple path is \(c, s, b, a, d\)(4 edges). If the DFS from \(s\) visits \(a\) first, then \(b\) and \(d\) are both discovered from \(a\), the edge \((s, b)\) is not in the DFS tree, and the longest path in the tree has only 3 edges.